package com.beta.cat.annotation;

import com.beta.cat.service.RedissonService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 基于 Redisson 的分布式锁注解的解析器
 *
 * @author kevin_zhang
 * @date 2021/1/7
 */
@Slf4j
@Aspect
@Component
public class DistributedLockHandler {

    @Autowired
    RedissonService redissonService;

    @Around("@annotation(distributedLock)")
    public void around(ProceedingJoinPoint joinPoint, DistributedLock distributedLock) {
        log.info("DistributedLockHandler.around start");
        String lockName = distributedLock.lockName();
        long leaseTime = distributedLock.lockTime();
        try {
            if (!redissonService.tryLock(lockName, leaseTime, 500)) {
                throw new IllegalStateException();
            }
            log.info("DistributedLockHandler.around 加锁完成");

            joinPoint.proceed();
        } catch (Throwable throwable) {
            log.error("DistributedLockHandler.around 加锁异常");
            throwable.printStackTrace();
        } finally {
            /**
             * 只有当前线程还持用该锁，才会释放锁
             */
            if (redissonService.isHeldByCurrentThread(lockName)) {
                redissonService.unlock(lockName);
            }
        }
        log.info("DistributedLockHandler.around end");
    }
}
